home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 19 / Mac Magazin and MacEasy Magazine CD - Issue 19.iso / Utilities / uae-0.4 / Source Code / newcpu.c < prev    next >
Text File  |  1996-02-05  |  59KB  |  2,630 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * MC68000 emulation
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   * 
  8.   */
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13.  
  14. #include "config.h"
  15. #include "amiga.h"
  16. #include "options.h"
  17. #include "events.h"
  18. #include "memory.h"
  19. #include "custom.h"
  20. #include "newcpu.h"
  21. #include "ersatz.h"
  22.  
  23. #undef COUNT_INSTRS
  24.  
  25. #ifdef COUNT_INSTRS
  26. static unsigned long int instrcount[65536];
  27. static UWORD opcodenums[65536];
  28.  
  29. int compfn(const void *el1, const void *el2)
  30. {
  31.     return instrcount[*(const UWORD *)el1] < instrcount[*(const UWORD *)el2];
  32. }
  33.  
  34. void dump_counts(void)
  35. {
  36.     FILE *f = fopen("insncount", "w");
  37.     unsigned long int total = 0;
  38.     int i;
  39.     
  40.     for(i=0; i < 65536; i++) {
  41.     opcodenums[i] = i;
  42.         total += instrcount[i];
  43.     }
  44.     qsort(opcodenums, 65536, sizeof(UWORD), compfn);
  45.     
  46.     fprintf(f, "Total: %ld\n", total);
  47.     for(i=0; i < 65536; i++) {
  48.     unsigned long int cnt = instrcount[opcodenums[i]];
  49.     if (!cnt)
  50.         break;
  51.     fprintf(f, "%04x: %ld\n", opcodenums[i], cnt);
  52.     }
  53.     fclose(f);
  54. }
  55. #endif
  56.  
  57. bool broken_in;
  58.  
  59. #ifdef DUALCPU
  60. bool allowmem;
  61. bool customacc;
  62. #endif
  63.  
  64. typedef enum {
  65.   Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r, 
  66.   absw, absl, PC16, PC8r, imm, imm3, ill2, ill3 
  67. } amodes;
  68.  
  69. typedef struct {
  70.   amodes mode;
  71.   UBYTE reg;
  72. } addr_mode;
  73.  
  74. static void set_addr_mode(addr_mode *a, int mode, int reg)
  75. {
  76.     a->mode = mode == 7 ? (amodes)((int)absw + reg) : (amodes)mode;
  77.     a->reg = reg;
  78. }
  79.  
  80. typedef enum {
  81.   RegD, RegA, Addr, EAIM
  82. } eatypes;
  83.  
  84. typedef struct {
  85.   ULONG addr;
  86.   eatypes type;
  87.   ULONG szmask;
  88. } effadr;
  89.  
  90. typedef struct {
  91.   addr_mode src,dest;
  92.   ULONG mask;
  93.   UWORD clogs;
  94. } instr_params;
  95.  
  96. typedef void instr_result;
  97. typedef instr_result (*instr_func)(const instr_params);
  98.  
  99. typedef struct {
  100.   instr_func execfunc;
  101.   instr_params params;
  102. } I_dec_tab_entry; 
  103.  
  104. static I_dec_tab_entry instr_dectab[65536]; 
  105.  
  106. static void GenerateDecTab(void);
  107.  
  108. void MC68000_init(void)
  109. {
  110. #ifdef COUNT_INSTRS
  111.     int i;
  112.     for(i=0;i<65536;i++) {
  113.     instrcount[i] = 0;
  114.     }
  115. #endif
  116.     GenerateDecTab();
  117. }
  118.  
  119. struct regstruct regs;
  120.  
  121. static ULONG sizemask(const int sz)
  122. {
  123.   switch(sz){
  124.   case 0: return 0xff;
  125.   case 1: return 0xffff;
  126.   case 2: return 0xffffffff;
  127.   default: abort();
  128.   }
  129. }
  130.  
  131. static __inline__ int mask2shift(const ULONG mask)
  132. {
  133.   if (mask == 0xff) return 7;
  134.   if (mask == 0xffff) return 15;
  135.   return 31;
  136. }
  137.  
  138. static __inline__ int mask2len(const ULONG mask)
  139. {
  140.   if (mask == 0xff) return 1;
  141.   if (mask == 0xffff) return 2;
  142.   return 4;
  143. }
  144.  
  145. static __inline__ ULONG ExtendWord(const ULONG v)
  146. {
  147.   return (LONG)(WORD)(v);
  148. }
  149.  
  150. static __inline__ ULONG ExtendByte(const ULONG v)
  151. {
  152.   return (LONG)(BYTE)(v);
  153. }
  154.  
  155. static __inline__ ULONG Extend(const ULONG v,const ULONG mask)
  156. {
  157.   switch(mask){
  158.   case 0xff: 
  159.     return (LONG)(BYTE)v;
  160.   case 0xffff:
  161.     return (LONG)(WORD)v;
  162.   default:
  163.     return v;
  164.   }
  165. }
  166.  
  167. static effadr GetEA(const addr_mode a, const ULONG mask)
  168. {
  169.   effadr ea;
  170.   UWORD dp;
  171.   BYTE disp8;
  172.   int r;
  173.   ULONG dispreg;
  174.  
  175.   ea.szmask = mask;
  176.   switch(a.mode){
  177.   case Dreg:
  178.     ea.addr = a.reg; ea.type = RegD; break;
  179.   case Areg:
  180.     ea.addr = a.reg; ea.type = RegA; break;
  181.   case Aind:
  182.     ea.addr = regs.a[a.reg]; ea.type = Addr; break;
  183.   case Aipi:
  184.     ea.addr = regs.a[a.reg]; 
  185.     if (a.reg == 7 && mask == 0xff) {
  186.       regs.a[a.reg] += 2;
  187.     } else {
  188.       regs.a[a.reg] += mask2len(mask);
  189.     }
  190.     ea.type = Addr; break;
  191.   case Apdi:
  192.     if (a.reg == 7 && mask == 0xff) {
  193.       ea.addr = regs.a[a.reg] -= 2;
  194.     } else {
  195.       ea.addr = regs.a[a.reg] -= mask2len(mask);
  196.     }
  197.     ea.type = Addr; break;
  198.   case Ad16:
  199.     ea.addr = regs.a[a.reg] + (WORD)nextiword();
  200.     ea.type = Addr; break;
  201.   case Ad8r:
  202.     dp = nextiword();
  203.     disp8 = dp & 0xFF;
  204.     r = (dp & 0x7000) >> 12;
  205.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
  206.  
  207.     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
  208.     ea.addr = regs.a[a.reg] + disp8 + dispreg;
  209.     ea.type = Addr; break;
  210.   case PC16:
  211.     ea.addr = m68k_getpc();
  212.     ea.addr += (WORD)nextiword();
  213.     ea.type = Addr; break;
  214.   case PC8r:
  215.     ea.addr = m68k_getpc();
  216.     dp = nextiword();
  217.     disp8 = dp & 0xFF;
  218.     r = (dp & 0x7000) >> 12;
  219.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
  220.  
  221.     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
  222.     ea.addr += disp8 + dispreg;
  223.     ea.type = Addr; break;
  224.   case absw:
  225.     ea.type = Addr;
  226.     ea.addr = (LONG)(WORD)nextiword();
  227.     break;
  228.   case absl:
  229.     ea.type = Addr;
  230.     ea.addr = nextilong();
  231.     break;
  232.   case imm:
  233.     switch(mask){
  234.     case 0xff:
  235.       ea.addr = ExtendByte(nextiword()); ea.type = EAIM; break;
  236.     case 0xffff:
  237.       ea.addr = ExtendWord(nextiword()); ea.type = EAIM; break;
  238.     case 0xffffffff:
  239.       ea.addr = nextilong(); ea.type = EAIM; break;
  240.     }
  241.     break;
  242.   case imm3:
  243.     ea.addr = a.reg; ea.type = EAIM; break;
  244.   default:
  245.     abort();
  246.   }
  247.   return ea;
  248. }
  249.  
  250. static effadr MGetEA(const addr_mode a, const ULONG mask)
  251. {
  252.   effadr ea;
  253.   UWORD dp;
  254.   BYTE disp8;
  255.   int r;
  256.   ULONG dispreg;
  257.  
  258.   ea.szmask = mask;
  259.   switch(a.mode){
  260.   case Aind: case Aipi: case Apdi:
  261.     ea.addr = regs.a[a.reg]; ea.type = Addr; break;
  262.   case Ad16:
  263.     ea.addr = regs.a[a.reg] + (WORD)nextiword();
  264.     ea.type = Addr; break;
  265.   case Ad8r:
  266.     dp = nextiword();
  267.     disp8 = dp & 0xFF;
  268.     r = (dp & 0x7000) >> 12;
  269.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
  270.  
  271.     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
  272.     ea.addr = regs.a[a.reg] + disp8 + dispreg;
  273.     ea.type = Addr; break;
  274.   case PC16:
  275.     ea.addr = m68k_getpc();
  276.     ea.addr += (WORD)nextiword(); 
  277.     ea.type = Addr; break;
  278.   case PC8r:
  279.     ea.addr = m68k_getpc();
  280.     dp = nextiword();
  281.     disp8 = dp & 0xFF;
  282.     r = (dp & 0x7000) >> 12;
  283.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
  284.  
  285.     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
  286.     ea.addr += disp8 + dispreg;
  287.     ea.type = Addr; break;
  288.   case absw:
  289.     ea.type = Addr;
  290.     ea.addr = (LONG)(WORD)nextiword();
  291.     break;
  292.   case absl:
  293.     ea.type = Addr;
  294.     ea.addr = nextilong();
  295.     break;
  296.   default:
  297.     abort();
  298.   }
  299.   return ea;
  300. }
  301.  
  302. static void MCompleteEAFromRL(effadr *ea, const addr_mode a, ULONG mask, UWORD bitmask)
  303. {
  304.     int bitcnt = 0;
  305.     int i;
  306.     for(i=0;i<16;i++) {
  307.     bitcnt += bitmask & 1;
  308.     bitmask >>= 1;
  309.     }
  310.     switch(a.mode){
  311.      case Aipi: 
  312.     abort(); break;
  313.      case Apdi:
  314.     ea->addr = regs.a[a.reg] -= bitcnt * mask2len(mask); break;
  315.      default: break;
  316.     }
  317. }
  318.  
  319. static void MCompleteEAToRL(effadr ea, const addr_mode a)
  320. {
  321.     switch(a.mode){
  322.      case Aipi: 
  323.     regs.a[a.reg] = ea.addr; break;
  324.      case Apdi:
  325.     abort(); break;
  326.      default: break;
  327.     }
  328. }
  329.  
  330. static ULONG RetrieveEA(const effadr ea)
  331. {
  332.     switch(ea.type){
  333.      case Addr:
  334.     return ea.addr;
  335.      default:
  336.     abort();
  337.     }
  338. }
  339.  
  340. static ULONG GetFromEA(const effadr ea)
  341. {
  342.     switch(ea.type) {
  343.      case RegD:
  344.     return Extend(regs.d[ea.addr],ea.szmask);
  345.      case RegA:
  346.     return Extend(regs.a[ea.addr],ea.szmask);
  347.      case Addr:
  348.     switch(ea.szmask){
  349.      case 0xff:
  350.         return ExtendByte(get_byte(ea.addr));
  351.      case 0xffff:
  352.         return ExtendWord(get_word(ea.addr));
  353.      case 0xffffffff:
  354.         return get_long(ea.addr);
  355.      default:
  356.         abort();
  357.     }
  358.      case EAIM:
  359.     return ea.addr;
  360.     }
  361.     return 0; /* Nnnnnnngghhh! */
  362. }
  363.  
  364. static void StoreToEA(const effadr ea, const ULONG value)
  365. {
  366.     switch(ea.type){
  367.      case RegD:
  368.     regs.d[ea.addr] &= ~ea.szmask; regs.d[ea.addr] |= (value & ea.szmask);
  369.     break;
  370.      case RegA:
  371.     regs.a[ea.addr] = value;
  372.     break;
  373.      case Addr:
  374.     switch(ea.szmask){
  375.      case 0xff:
  376.         put_byte(ea.addr,value);
  377.         break;
  378.      case 0xffff:
  379.         put_word(ea.addr,value);
  380.         break;
  381.      case 0xffffffff:
  382.         put_long(ea.addr,value);
  383.         break;
  384.      default:
  385.         abort();
  386.     }
  387.     break;
  388.      default:
  389.     abort();
  390.   }
  391. }
  392.  
  393. static effadr ShowEA(addr_mode a,ULONG mask)
  394. {
  395.     effadr ea;
  396.     UWORD dp;
  397.     BYTE disp8;
  398.     WORD disp16;
  399.     int r;
  400.     ULONG dispreg;
  401.     
  402.     ea.szmask = mask;
  403.     switch(a.mode){
  404.      case Dreg:
  405.     ea.addr = a.reg; ea.type = RegD; 
  406.     printf("D%d", (int)a.reg);
  407.     break;
  408.      case Areg:
  409.     ea.addr = a.reg; ea.type = RegA;
  410.     printf("A%d", (int)a.reg);
  411.     break;
  412.      case Aind:
  413.     ea.addr = regs.a[a.reg]; ea.type = Addr; 
  414.     printf("(A%d)", (int)a.reg);
  415.     break;
  416.      case Aipi:
  417.     ea.addr = regs.a[a.reg]; 
  418.     ea.type = Addr; 
  419.     printf("(A%d)+", (int)a.reg);
  420.     break;
  421.      case Apdi:
  422.     ea.addr = regs.a[a.reg] - mask2len(mask); ea.type = Addr; 
  423.     printf("-(A%d)", (int)a.reg);
  424.     break;
  425.      case Ad16:
  426.     disp16 = nextiword();
  427.     ea.addr = regs.a[a.reg] + (WORD)disp16;
  428.     ea.type = Addr; 
  429.     printf("(A%d,$%08lx) == $%08lx", (int)a.reg, disp16, ea.addr);
  430.     break;
  431.      case Ad8r:
  432.     dp = nextiword();
  433.     disp8 = dp & 0xFF;
  434.     r = (dp & 0x7000) >> 12;
  435.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
  436.     
  437.     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
  438.     ea.addr = regs.a[a.reg] + disp8 + dispreg;
  439.     ea.type = Addr;
  440.     printf("(A%d, %c%d.%c, $%02x) == $%08lx", (int)a.reg, 
  441.            dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', disp8,
  442.            ea.addr);
  443.     break;
  444.      case PC16:
  445.     ea.addr = m68k_getpc();
  446.     disp16 = nextiword();
  447.     ea.addr += (WORD)disp16;
  448.     ea.type = Addr; 
  449.     printf("(PC,$%08lx) == $%08lx", disp16, ea.addr);
  450.     break;
  451.      case PC8r:
  452.     ea.addr = m68k_getpc();
  453.     dp = nextiword();
  454.     disp8 = dp & 0xFF;
  455.     r = (dp & 0x7000) >> 12;
  456.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
  457.     
  458.     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
  459.     ea.addr += disp8 + dispreg;
  460.     ea.type = Addr; 
  461.     printf("(PC, %c%d.%c, $%02x) == $%08lx", dp & 0x8000 ? 'A' : 'D', 
  462.            (int)r, dp & 0x800 ? 'L' : 'W', disp8, ea.addr);
  463.     break;
  464.      case absw:
  465.     ea.type = Addr;
  466.     ea.addr = (LONG)(WORD)nextiword();
  467.     printf("$%08lx", ea.addr);
  468.     break;
  469.      case absl:
  470.     ea.type = Addr;
  471.     ea.addr = nextilong();
  472.     printf("$%08lx", ea.addr);
  473.     break;
  474.      case imm:
  475.     switch(mask){
  476.      case 0xff:
  477.         ea.addr = nextiword() & 0xff; ea.type = EAIM; break;
  478.      case 0xffff:
  479.         ea.addr = nextiword(); ea.type = EAIM; break;
  480.      case 0xffffffff:
  481.         ea.addr = nextilong(); ea.type = EAIM; break;
  482.     }
  483.     printf("#$%08lx", ea.addr);
  484.     break;
  485.      case imm3:
  486.     ea.addr = a.reg; ea.type = EAIM;
  487.     printf("#$%08lx", ea.addr);
  488.     break;
  489.      default:
  490.     abort();
  491.     }
  492.     return ea;
  493. }
  494.  
  495. static void SuperState(void)
  496. {
  497.     if (!regs.s){
  498.     CPTR temp = regs.usp;
  499.     regs.s = 1; 
  500.     regs.t = 0;
  501.     regs.usp = regs.a[7];
  502.     regs.a[7] = temp;
  503.     }
  504. }
  505.  
  506. static void UserState(void)
  507. {
  508.     if (regs.s){
  509.     CPTR temp = regs.usp;
  510.     regs.s = 0; 
  511.     /* regs.t = 0; */
  512.     regs.usp = regs.a[7];
  513.     regs.a[7] = temp;
  514.     }
  515. }
  516.  
  517. void MakeSR(void)
  518. {
  519.     assert((regs.n & 1) == regs.n);
  520.     assert((regs.s & 1) == regs.s);
  521.     assert((regs.x & 1) == regs.x);
  522.     assert((regs.c & 1) == regs.c);
  523.     assert((regs.v & 1) == regs.v);
  524.     assert((regs.z & 1) == regs.z);
  525.     regs.sr = ((regs.t << 15) | (regs.s << 13) | (regs.intmask << 8)
  526.            | (regs.x << 4) | (regs.n << 3) | (regs.z << 2) | (regs.v << 1) 
  527.            |  regs.c);
  528. }
  529.  
  530. void MakeFromSR(void)
  531. {
  532.     int olds = regs.s;
  533.  
  534.     regs.t = (regs.sr >> 15) & 1;
  535.     regs.s = (regs.sr >> 13) & 1;
  536.     regs.intmask = (regs.sr >> 8) & 7;
  537.     regs.x = (regs.sr >> 4) & 1;
  538.     regs.n = (regs.sr >> 3) & 1;
  539.     regs.z = (regs.sr >> 2) & 1;
  540.     regs.v = (regs.sr >> 1) & 1;
  541.     regs.c = regs.sr & 1;
  542.     if (olds != regs.s) {
  543.     regs.s = olds; 
  544.     if (regs.s) UserState(); else SuperState();
  545.     }
  546.     specialflags |= SPCFLAG_INT;
  547.     if (regs.t)
  548.         specialflags |= SPCFLAG_TRACE;
  549.     else
  550.         specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
  551. }
  552.  
  553. void Exception(int nr)
  554. {
  555.     addr_mode pda7 = { Apdi, 7 };
  556.     effadr lea;
  557.     effadr wea;
  558.     
  559.     MakeSR();
  560.     SuperState();
  561.     lea = GetEA(pda7,0xffffffff);
  562.     wea = GetEA(pda7,0xffff);
  563.     StoreToEA(wea,regs.sr);
  564.     StoreToEA(lea,m68k_getpc());
  565.     m68k_setpc(get_long(4*nr));
  566.     regs.t = 0;
  567.     specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
  568. }
  569.  
  570. static void Interrupt(int nr)
  571. {
  572.     assert(nr < 8 && nr >= 0);
  573.     Exception(nr+24);
  574.     
  575.     regs.intmask = nr;
  576.     specialflags |= SPCFLAG_INT;
  577. }
  578.  
  579.  /*
  580.   * instruction emulations
  581.   */
  582.  
  583. static instr_result INST_ILLG(const instr_params p)
  584. {
  585.   m68k_setpc(m68k_getpc()-2);
  586.   
  587.   Exception(4);
  588. }
  589.  
  590. static instr_result INST_NIMP(const instr_params p)
  591. {
  592.   INST_ILLG(p);
  593. }
  594.  
  595. static instr_result INST_OR(const instr_params p)
  596. {
  597.     effadr src = GetEA(p.src, p.mask);
  598.     ULONG srcv = GetFromEA(src);
  599.     effadr dst = GetEA(p.dest, p.mask);
  600.     ULONG dstv = GetFromEA(dst);
  601.     dstv |= srcv;
  602.     setflags_logical(dstv, p.mask);
  603.     StoreToEA(dst,dstv);
  604. }
  605.  
  606. static instr_result INST_AND(const instr_params p)
  607. {
  608.   effadr src = GetEA(p.src, p.mask);
  609.   ULONG srcv = GetFromEA(src);
  610.   effadr dst = GetEA(p.dest, p.mask);
  611.   ULONG dstv = GetFromEA(dst);
  612.   dstv &= srcv;
  613.   setflags_logical(dstv, p.mask);
  614.   StoreToEA(dst,dstv);
  615. }
  616.  
  617. static instr_result INST_EOR(const instr_params p)
  618. {
  619.   effadr src = GetEA(p.src, p.mask);
  620.   ULONG srcv = GetFromEA(src);
  621.   effadr dst = GetEA(p.dest, p.mask);
  622.   ULONG dstv = GetFromEA(dst);
  623.   dstv ^= srcv;
  624.   setflags_logical(dstv, p.mask);
  625.   StoreToEA(dst,dstv);
  626. }
  627.  
  628. static instr_result INST_CMP(const instr_params p)
  629. {
  630.   effadr src = GetEA(p.src, p.mask);
  631.   ULONG srcv = GetFromEA(src);
  632.   effadr dst = GetEA(p.dest, p.mask);
  633.   ULONG dstv = GetFromEA(dst);
  634.   ULONG newv = dstv - srcv;
  635.   setflags_cmp(srcv, dstv, newv, p.mask);
  636. }
  637.  
  638. static instr_result INST_ADD(const instr_params p)
  639. {
  640.   effadr src = GetEA(p.src, p.mask);
  641.   ULONG srcv = GetFromEA(src);
  642.   effadr dst = GetEA(p.dest, p.mask);
  643.   ULONG dstv = GetFromEA(dst);
  644.   ULONG newv = dstv + srcv;
  645.   setflags_add(srcv, dstv, newv, p.mask);
  646.   StoreToEA(dst,newv);
  647. }
  648.  
  649. static instr_result INST_SUB(const instr_params p)
  650. {
  651.   effadr src = GetEA(p.src, p.mask);
  652.   ULONG srcv = GetFromEA(src);
  653.   effadr dst = GetEA(p.dest, p.mask);
  654.   ULONG dstv = GetFromEA(dst);
  655.   ULONG newv = dstv - srcv;
  656.   setflags_sub(srcv, dstv, newv, p.mask);
  657.   StoreToEA(dst,newv);
  658. }
  659.  
  660. static instr_result INST_ADDX(const instr_params p)
  661. {
  662.   effadr src = GetEA(p.src, p.mask);
  663.   ULONG srcv = GetFromEA(src);
  664.   effadr dst = GetEA(p.dest, p.mask);
  665.   ULONG dstv = GetFromEA(dst);
  666.   ULONG newv = dstv + srcv + regs.x;
  667.   setflags_addx(srcv, dstv, newv, p.mask);
  668.   StoreToEA(dst,newv);
  669. }
  670.  
  671. static instr_result INST_SUBX(const instr_params p)
  672. {
  673.   effadr src = GetEA(p.src, p.mask);
  674.   ULONG srcv = GetFromEA(src);
  675.   effadr dst = GetEA(p.dest, p.mask);
  676.   ULONG dstv = GetFromEA(dst);
  677.   ULONG newv = dstv - srcv - regs.x;
  678.   setflags_subx(srcv, dstv, newv, p.mask);
  679.   StoreToEA(dst,newv);
  680. }
  681.  
  682. static instr_result INST_ADDA(const instr_params p)
  683. {
  684.   effadr src = GetEA(p.src, p.mask);
  685.   ULONG srcv = GetFromEA(src);
  686.   effadr dst = GetEA(p.dest, 0xffffffff);
  687.   ULONG dstv = GetFromEA(dst);
  688.   StoreToEA(dst,dstv + srcv);
  689. }
  690.  
  691. static instr_result INST_SUBA(const instr_params p)
  692. {
  693.   effadr src = GetEA(p.src, p.mask);
  694.   ULONG srcv = GetFromEA(src);
  695.   effadr dst = GetEA(p.dest, 0xffffffff);
  696.   ULONG dstv = GetFromEA(dst);
  697.   StoreToEA(dst,dstv - srcv);
  698. }
  699.  
  700. static instr_result INST_CMPA(const instr_params p)
  701. {
  702.   effadr src = GetEA(p.src, p.mask);
  703.   ULONG srcv = GetFromEA(src);
  704.   effadr dst = GetEA(p.dest, 0xffffffff);
  705.   ULONG dstv = GetFromEA(dst);
  706.   ULONG newv = dstv - srcv;
  707.   setflags_cmp(srcv, dstv, newv, 0xffffffff);
  708. }
  709.  
  710. static instr_result INST_CHK(const instr_params p)
  711. {
  712.   fprintf(stderr, "CHK occurred\n");
  713.   INST_ILLG(p);
  714. }
  715.  
  716. static instr_result INST_EXGL(const instr_params p)
  717. {
  718.   effadr src = GetEA(p.src, p.mask);
  719.   ULONG srcv = GetFromEA(src);
  720.   effadr dst = GetEA(p.dest, p.mask);
  721.   ULONG dstv = GetFromEA(dst);
  722.   StoreToEA(dst,srcv);
  723.   StoreToEA(src,dstv);  
  724. }
  725.  
  726. static instr_result INST_LEA(const instr_params p)
  727. {
  728.   effadr src = GetEA(p.src, p.mask);
  729.   effadr dst = GetEA(p.dest, p.mask);
  730.   StoreToEA(dst,RetrieveEA(src));
  731. }
  732.  
  733. static instr_result INST_MOVE(const instr_params p)
  734. {
  735.   effadr src = GetEA(p.src, p.mask);
  736.   ULONG srcv = GetFromEA(src);
  737.   effadr dst = GetEA(p.dest, p.mask);
  738.   setflags_logical(srcv,p.mask);
  739.   StoreToEA(dst,srcv);
  740. }
  741.  
  742. static instr_result INST_MOVEQ(const instr_params p)
  743. {
  744.   effadr src = GetEA(p.src, p.mask);
  745.   effadr dst = GetEA(p.dest, p.mask);
  746.   ULONG srcv = ExtendByte(GetFromEA(src));
  747.   setflags_logical(srcv,p.mask);
  748.   StoreToEA(dst,srcv);
  749. }
  750.  
  751. static instr_result INST_MOVEA(const instr_params p)
  752. {
  753.   effadr src = GetEA(p.src, p.mask);
  754.   ULONG srcv = GetFromEA(src);
  755.   effadr dst = GetEA(p.dest, p.mask);
  756.   StoreToEA(dst,srcv);
  757. }
  758.  
  759. static instr_result INST_BTST(const instr_params p)
  760. {
  761.   effadr src = GetEA(p.src, p.mask);
  762.   ULONG srcv = GetFromEA(src);
  763.   effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
  764.   ULONG dstv = GetFromEA(dst);
  765.   if (p.dest.mode == Dreg) {
  766.     srcv &= 31;
  767.   } else {
  768.     srcv &= 7; 
  769.   }
  770.   regs.z = !(dstv & (1 << srcv));
  771. }
  772.  
  773. static instr_result INST_BCLR(const instr_params p)
  774. {
  775.   effadr src = GetEA(p.src, p.mask);
  776.   ULONG srcv = GetFromEA(src);
  777.   effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
  778.   ULONG dstv = GetFromEA(dst);
  779.   if (p.dest.mode == Dreg) {
  780.     srcv &= 31;
  781.   } else {
  782.     srcv &= 7; 
  783.   }
  784.   regs.z = !(dstv & (1 << srcv));
  785.   StoreToEA(dst,dstv & ~(1 << srcv));
  786. }
  787.  
  788. static instr_result INST_BSET(const instr_params p)
  789. {
  790.   effadr src = GetEA(p.src, p.mask);
  791.   ULONG srcv = GetFromEA(src);
  792.   effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
  793.   ULONG dstv = GetFromEA(dst);
  794.   if (p.dest.mode == Dreg) {
  795.     srcv &= 31; 
  796.   } else {
  797.     srcv &= 7; 
  798.   }
  799.   regs.z = !(dstv & (1 << srcv));
  800.   StoreToEA(dst,dstv | (1 << srcv));
  801. }
  802.  
  803. static instr_result INST_BCHG(const instr_params p)
  804. {
  805.   effadr src = GetEA(p.src, p.mask);
  806.   ULONG srcv = GetFromEA(src);
  807.   effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
  808.   ULONG dstv = GetFromEA(dst);
  809.   if (p.dest.mode == Dreg) {
  810.     srcv &= 31; 
  811.   } else {
  812.     srcv &= 7; 
  813.   }
  814.   regs.z = !(dstv & (1 << srcv));
  815.   StoreToEA(dst,dstv ^ (1 << srcv));
  816. }
  817.  
  818. static instr_result INST_NEG(const instr_params p)
  819. {
  820.   effadr ea = GetEA(p.src, p.mask);
  821.   ULONG val = GetFromEA(ea);
  822.   ULONG newv = -val;
  823.   setflags_sub(val, 0, newv, p.mask);
  824.   StoreToEA(ea,newv);
  825. }
  826.  
  827. static instr_result INST_NEGX(const instr_params p)
  828. {
  829.   effadr ea = GetEA(p.src, p.mask);
  830.   ULONG val = GetFromEA(ea);
  831.   ULONG newv = -val-regs.x;
  832.   setflags_sub(val, 0, newv, p.mask);
  833.   StoreToEA(ea,newv);
  834. }
  835.  
  836. static instr_result INST_NOT(const instr_params p)
  837. {
  838.   effadr ea = GetEA(p.src, p.mask);
  839.   ULONG val = GetFromEA(ea);
  840.   ULONG newv = ~val;
  841.   setflags_logical(newv,p.mask);
  842.   StoreToEA(ea,newv);
  843. }
  844.  
  845. static instr_result INST_CLR(const instr_params p)
  846. {
  847.   effadr ea = GetEA(p.src, p.mask);
  848.   ULONG newv = 0;
  849.   setflags_logical(newv,p.mask);
  850.   StoreToEA(ea,newv);
  851. }
  852.  
  853. static instr_result INST_TST(const instr_params p)
  854. {
  855.   effadr ea = GetEA(p.src, p.mask);
  856.   ULONG val = GetFromEA(ea);
  857.   setflags_logical(val,p.mask);
  858. }
  859.  
  860. static instr_result INST_SWAP(const instr_params p)
  861. {
  862.   effadr ea = GetEA(p.src, p.mask);
  863.   ULONG val = GetFromEA(ea);
  864.   val = (val >> 16) | (val << 16);
  865.   StoreToEA(ea, val);
  866.   setflags_logical(val,p.mask);
  867. }
  868.  
  869. static instr_result INST_EXTW(const instr_params p)
  870. {
  871.   effadr ea = GetEA(p.src, p.mask);
  872.   ULONG val = ExtendByte(GetFromEA(ea));
  873.   setflags_logical(val,p.mask);  
  874.   StoreToEA(ea, val);
  875. }
  876.  
  877. static instr_result INST_EXTL(const instr_params p)
  878. {
  879.   effadr ea = GetEA(p.src, p.mask);
  880.   ULONG val = ExtendWord(GetFromEA(ea));
  881.   setflags_logical(val,p.mask);  
  882.   StoreToEA(ea, val);
  883. }
  884.  
  885. static instr_result INST_Scc(const instr_params p)
  886. {
  887.   effadr ea = GetEA(p.src, p.mask);
  888.   StoreToEA(ea,cctrue(p.dest.reg) ? 0xff : 0);
  889. }
  890.  
  891. static instr_result INST_ABCD(const instr_params p)
  892. {
  893.   abort();
  894. }
  895.  
  896. static instr_result INST_SBCD(const instr_params p)
  897. {
  898.   abort(); 
  899. }
  900.  
  901. static instr_result INST_NBCD(const instr_params p)
  902. {
  903.   abort(); 
  904. }
  905.  
  906. static instr_result INST_NOP(const instr_params p)
  907. {
  908.   
  909. }
  910.  
  911. static instr_result INST_RESET(const instr_params p)
  912. {
  913.   customreset();
  914. }
  915.  
  916. static instr_result INST_STOP(const instr_params p)
  917. {
  918.   if ((p.mask != 0xff) && !regs.s) {
  919.     m68k_setpc(m68k_getpc()-2);
  920.     Exception(8);
  921.   } else {
  922.     effadr ea = GetEA(p.src, p.mask);
  923.     regs.sr = GetFromEA(ea);
  924.     MakeFromSR();
  925.     regs.stopped = 1;
  926.   }
  927. }
  928.  
  929. static instr_result INST_TRAPV(const instr_params p)
  930. {
  931.   if (regs.v) Exception(7);
  932. }
  933.  
  934. static instr_result INST_TRAP(const instr_params p)
  935. {
  936.   UWORD val = GetFromEA(GetEA(p.src,p.mask));
  937.   Exception(val+32);
  938. }
  939.  
  940. static instr_result INST_BSRB(const instr_params p)
  941. {
  942.   addr_mode pda7 = { Apdi, 7 };
  943.   effadr ea = GetEA(p.src, p.mask);
  944.   BYTE offset = GetFromEA(ea);
  945.   effadr stackp;
  946.   stackp = GetEA(pda7,0xffffffff);
  947.   StoreToEA(stackp,m68k_getpc());
  948.   m68k_setpc(m68k_getpc() + offset);
  949.  
  950. }
  951.  
  952. static instr_result INST_BccB(const instr_params p)
  953. {
  954.   if (cctrue(p.dest.reg)){
  955.     effadr ea = GetEA(p.src, p.mask);
  956.     BYTE offset = GetFromEA(ea);
  957.     m68k_setpc(m68k_getpc() + offset);
  958.   }
  959. }
  960.  
  961. static instr_result INST_BSRW(const instr_params p)
  962. {
  963.   addr_mode pda7 = { Apdi, 7 };
  964.   effadr ea = GetEA(p.src, p.mask);
  965.   WORD offset = GetFromEA(ea);
  966.   effadr stackp;
  967.   stackp = GetEA(pda7,0xffffffff);
  968.   StoreToEA(stackp,m68k_getpc());
  969.   m68k_setpc(m68k_getpc() + offset - 2);
  970. }
  971.  
  972. static instr_result INST_BccW(const instr_params p)
  973. {
  974.   effadr ea = GetEA(p.src, p.mask);
  975.   WORD offset = GetFromEA(ea);
  976.   if (cctrue(p.dest.reg)){
  977.     m68k_setpc(m68k_getpc() + offset - 2);
  978.   }
  979. }
  980.  
  981. static instr_result INST_DBcc(const instr_params p)
  982. {
  983.   WORD offset = nextiword();
  984.  
  985.   if (!cctrue(p.dest.reg)){
  986.     effadr ea = GetEA(p.src, p.mask); /* safe inside if, can only be Dreg */
  987.     ULONG dr = GetFromEA(ea);
  988.     if (dr--){
  989.       m68k_setpc(m68k_getpc() + offset - 2);
  990.     }
  991.     StoreToEA(ea,dr);
  992.   }
  993. }
  994.  
  995. static instr_result INST_JMP(const instr_params p)
  996. {
  997.   effadr ea = GetEA(p.src, p.mask);
  998.   m68k_setpc(RetrieveEA(ea));
  999. }
  1000.  
  1001. static instr_result INST_JSR(const instr_params p)
  1002. {
  1003.   effadr ea = GetEA(p.src, p.mask);
  1004.   addr_mode pda7 = { Apdi, 7 };
  1005.   effadr stackp;
  1006.   stackp = GetEA(pda7,0xffffffff);
  1007.   StoreToEA(stackp, m68k_getpc());
  1008.  
  1009.   m68k_setpc(RetrieveEA(ea));
  1010. }
  1011.  
  1012. static instr_result INST_RTE(const instr_params p)
  1013. {
  1014.   addr_mode a7pi = { Aipi, 7 };
  1015.   effadr stackp;
  1016.   stackp = GetEA(a7pi,0xffff);
  1017.   regs.sr = GetFromEA(stackp);
  1018.   stackp = GetEA(a7pi,0xffffffff);
  1019.   m68k_setpc(GetFromEA(stackp));
  1020.   MakeFromSR();
  1021. }
  1022.  
  1023. static instr_result INST_RTD(const instr_params p)
  1024. {
  1025.   INST_NIMP(p); 
  1026. }
  1027.  
  1028. static instr_result INST_RTS(const instr_params p)
  1029. {
  1030.   addr_mode a7pi = { Aipi, 7 };
  1031.   effadr stackp;
  1032.   stackp = GetEA(a7pi,0xffffffff);
  1033.   m68k_setpc(GetFromEA(stackp));
  1034. }
  1035.  
  1036. static instr_result INST_RTR(const instr_params p)
  1037. {
  1038.   addr_mode a7pi = { Aipi, 7 };
  1039.   effadr stackp;
  1040.   stackp = GetEA(a7pi,0xffff);
  1041.   MakeSR();
  1042.   regs.sr &= 0xff00;
  1043.   regs.sr |= GetFromEA(stackp) & 0xff;
  1044.   stackp = GetEA(a7pi,0xffffffff);
  1045.   m68k_setpc(GetFromEA(stackp));
  1046.   MakeFromSR();
  1047. }
  1048.  
  1049. static instr_result INST_LINK(const instr_params p)
  1050. {
  1051.     addr_mode pda7 = { Apdi, 7 };
  1052.     effadr stackp, ar, ea;
  1053.     ULONG offset;
  1054.     stackp = GetEA(pda7,0xffffffff);
  1055.     ar = GetEA(p.src, 0xffffffff);
  1056.     ea = GetEA(p.dest, p.mask);
  1057.     StoreToEA(stackp, GetFromEA(ar));
  1058.     StoreToEA(ar, regs.a[7]);
  1059.     offset = GetFromEA(ea);
  1060.     regs.a[7] += offset;
  1061. }
  1062.  
  1063. static instr_result INST_UNLK(const instr_params p)
  1064. {
  1065.   addr_mode a7pi = { Aipi, 7 };
  1066.   effadr stackp, ar;
  1067.   stackp = GetEA(a7pi,0xffffffff);
  1068.   ar = GetEA(p.src, 0xffffffff);
  1069.   regs.a[7] = GetFromEA(ar);
  1070.  
  1071.   StoreToEA(ar, GetFromEA(stackp));
  1072. }
  1073.  
  1074. static instr_result INST_MULU(const instr_params p)
  1075. {
  1076.   effadr src = GetEA(p.src, p.mask);
  1077.   UWORD srcv = GetFromEA(src);
  1078.   effadr dst = GetEA(p.dest, p.mask);
  1079.   UWORD dstv = GetFromEA(dst);
  1080.   ULONG newv = (ULONG)dstv * (ULONG)srcv;
  1081.   setflags_logical(newv, 0xffffffff);
  1082.   dst.szmask = 0xffffffff;
  1083.   StoreToEA(dst,newv);
  1084. }
  1085.  
  1086. static instr_result INST_MULS(const instr_params p)
  1087. {
  1088.   effadr src = GetEA(p.src, p.mask);
  1089.   WORD srcv = GetFromEA(src);
  1090.   effadr dst = GetEA(p.dest, p.mask);
  1091.   WORD dstv = GetFromEA(dst);
  1092.   ULONG newv = (LONG)dstv * (LONG)srcv;
  1093.   setflags_logical(newv, 0xffffffff);
  1094.   dst.szmask = 0xffffffff;
  1095.   StoreToEA(dst,newv);
  1096. }
  1097.  
  1098. static instr_result INST_DIVU(const instr_params p)
  1099. {
  1100.   effadr src = GetEA(p.src, 0xffff);
  1101.   UWORD srcv = GetFromEA(src);
  1102.   effadr dst = GetEA(p.dest, 0xffffffff);
  1103.   ULONG dstv = GetFromEA(dst);
  1104.   if (srcv == 0){
  1105.     /* FOO ! */
  1106.   } else {
  1107.     ULONG newv = dstv / srcv;
  1108.     UWORD rem = dstv % srcv;
  1109.     setflags_logical(newv, 0xffff);
  1110.     regs.v = newv > 0xffff;
  1111.     newv = (newv & 0xffff) | (rem << 16);
  1112.     StoreToEA(dst,newv);
  1113.   }
  1114. }
  1115.  
  1116. static instr_result INST_DIVS(const instr_params p)
  1117. {
  1118.   effadr src = GetEA(p.src, 0xffff);
  1119.   WORD srcv = GetFromEA(src);
  1120.   effadr dst = GetEA(p.dest, 0xffffffff);
  1121.   LONG dstv = GetFromEA(dst);
  1122.   if (srcv == 0){
  1123.     /* FOO ! */
  1124.   } else {
  1125.     LONG newv = dstv / srcv;
  1126.     UWORD rem = dstv % srcv;
  1127.     if ((rem & 0x8000) != (newv & 0x8000)) rem = -rem;
  1128.     setflags_logical(newv, 0xffff);
  1129.     regs.v = (newv & 0xffff0000) && (newv & 0xffff0000) != 0xffff0000;
  1130.     newv = (newv & 0xffff) | (rem << 16);
  1131.     StoreToEA(dst,newv);
  1132.   }
  1133. }
  1134.  
  1135. static instr_result INST_ASL(const instr_params p)
  1136. {
  1137.   effadr src = GetEA(p.src, p.mask);
  1138.   effadr dst = GetEA(p.dest, p.mask);
  1139.   ULONG cnt = GetFromEA(src) & 63;
  1140.   ULONG data = GetFromEA(dst) & p.mask;
  1141.  
  1142.   ULONG cmask = 1 << mask2shift(p.mask);
  1143.   ULONG sign = data & cmask;
  1144.   regs.v = 0;
  1145.   for (;cnt;--cnt){
  1146.     regs.c = regs.x = (data & cmask) != 0;
  1147.     data <<= 1;
  1148.     if ((data & cmask) != sign) regs.v = 1; 
  1149.   }
  1150.   regs.n = (data & cmask) != 0;
  1151.   regs.z = (data & p.mask) == 0;
  1152.   StoreToEA(dst,data);
  1153. }
  1154.  
  1155. static instr_result INST_ASR(const instr_params p)
  1156. {
  1157.   effadr src = GetEA(p.src, p.mask);
  1158.   effadr dst = GetEA(p.dest, p.mask);
  1159.   ULONG cnt = GetFromEA(src) & 63;
  1160.   ULONG data = GetFromEA(dst) & p.mask;
  1161.  
  1162.   ULONG cmask = 1 << mask2shift(p.mask);
  1163.   ULONG sign = data & cmask;
  1164.   regs.v = 0;
  1165.   for (;cnt;--cnt){
  1166.     regs.c = regs.x = data & 1;
  1167.     data = (data >> 1) | sign;
  1168.   }
  1169.   regs.n = sign != 0;
  1170.   regs.z = (data & p.mask) == 0;
  1171.   StoreToEA(dst,data);
  1172. }
  1173.  
  1174. static instr_result INST_LSR(const instr_params p)
  1175. {
  1176.   effadr src = GetEA(p.src, p.mask);
  1177.   effadr dst = GetEA(p.dest, p.mask);
  1178.   ULONG cnt = GetFromEA(src) & 63;
  1179.   ULONG data = GetFromEA(dst) & p.mask; 
  1180.  
  1181.   int carry = 0;
  1182.   for (;cnt;--cnt){
  1183.     carry = data & 1;
  1184.     data >>= 1;
  1185.   }
  1186.   setflags_logical(data,p.mask);
  1187.   regs.c = regs.x = carry;
  1188.   StoreToEA(dst,data);
  1189. }
  1190.  
  1191. static instr_result INST_LSL(const instr_params p)
  1192. {
  1193.   effadr src = GetEA(p.src, p.mask);
  1194.   effadr dst = GetEA(p.dest, p.mask);
  1195.   ULONG cnt = GetFromEA(src) & 63;
  1196.   ULONG data = GetFromEA(dst) & p.mask;
  1197.  
  1198.   ULONG cmask = 1 << mask2shift(p.mask);
  1199.   ULONG carry = 0;
  1200.  
  1201.   for (;cnt;--cnt){
  1202.     carry = data & cmask;
  1203.     data <<= 1;
  1204.   }
  1205.   setflags_logical(data,p.mask);
  1206.   regs.c = regs.x = carry != 0;
  1207.   StoreToEA(dst,data);
  1208. }
  1209.  
  1210. static instr_result INST_ROR(const instr_params p)
  1211. {
  1212.   effadr src = GetEA(p.src, p.mask);
  1213.   effadr dst = GetEA(p.dest, p.mask);
  1214.   ULONG cnt = GetFromEA(src) & 63;
  1215.   ULONG data = GetFromEA(dst) & p.mask;
  1216.  
  1217.   ULONG cmask = 1 << mask2shift(p.mask);
  1218.   int carry = 0;
  1219.   for (;cnt;--cnt){
  1220.     carry = data & 1;
  1221.     data >>= 1;
  1222.     if (carry) data |= cmask;
  1223.   }
  1224.   setflags_logical(data,p.mask);
  1225.   regs.c = carry;
  1226.   StoreToEA(dst,data);
  1227. }
  1228.  
  1229. static instr_result INST_ROL(const instr_params p)
  1230. {
  1231.   effadr src = GetEA(p.src, p.mask);
  1232.   effadr dst = GetEA(p.dest, p.mask);
  1233.   ULONG cnt = GetFromEA(src) & 63;
  1234.   ULONG data = GetFromEA(dst) & p.mask;
  1235.  
  1236.   ULONG cmask = 1 << mask2shift(p.mask);
  1237.   ULONG carry = 0;
  1238.  
  1239.   for (;cnt;--cnt){
  1240.     carry = data & cmask;
  1241.     data <<= 1;
  1242.     if (carry) data |= 1;
  1243.   }
  1244.   setflags_logical(data,p.mask);
  1245.   regs.c = carry != 0;
  1246.   StoreToEA(dst,data);
  1247. }
  1248.  
  1249. static instr_result INST_ROXR(const instr_params p)
  1250. {
  1251.   effadr src = GetEA(p.src, p.mask);
  1252.   effadr dst = GetEA(p.dest, p.mask);
  1253.   ULONG cnt = GetFromEA(src) & 63;
  1254.   ULONG data = GetFromEA(dst) & p.mask;
  1255.  
  1256.   ULONG cmask = 1 << mask2shift(p.mask);
  1257.   int carry = 0;
  1258.   for (;cnt;--cnt){
  1259.     carry = data & 1;
  1260.     data >>= 1;
  1261.     if (regs.x) data |= cmask;
  1262.     regs.x = carry;
  1263.   }
  1264.   setflags_logical(data,p.mask);
  1265.   regs.c = regs.x = carry;
  1266.   StoreToEA(dst,data);
  1267. }
  1268.  
  1269. static instr_result INST_ROXL(const instr_params p)
  1270. {
  1271.   effadr src = GetEA(p.src, p.mask);
  1272.   effadr dst = GetEA(p.dest, p.mask);
  1273.   ULONG cnt = GetFromEA(src) & 63;
  1274.   ULONG data = GetFromEA(dst) & p.mask;
  1275.  
  1276.   ULONG cmask = 1 << mask2shift(p.mask);
  1277.   int carry = 0;
  1278.  
  1279.   for (;cnt;--cnt){
  1280.     carry = data & cmask;
  1281.     data <<= 1;
  1282.     if (regs.x) data |= 1;
  1283.     regs.x = carry != 0;
  1284.   }
  1285.   setflags_logical(data,p.mask);
  1286.   regs.c = regs.x = carry != 0;
  1287.   StoreToEA(dst,data);
  1288. }
  1289.  
  1290. static instr_result INST_ASL1(const instr_params p)
  1291. {
  1292.   effadr dst = GetEA(p.dest, p.mask);
  1293.   ULONG data = GetFromEA(dst) & p.mask;
  1294.  
  1295.   ULONG cmask = 1 << mask2shift(p.mask);
  1296.   ULONG sign = data & cmask;
  1297.   regs.v = 0;
  1298.   regs.c = regs.x = sign != 0;
  1299.   data <<= 1;
  1300.   if ((data & cmask) != sign) regs.v = 1; 
  1301.   regs.n = (data & cmask) != 0;
  1302.   regs.z = (data & p.mask) == 0;
  1303.   StoreToEA(dst,data);
  1304. }
  1305.  
  1306. static instr_result INST_ASR1(const instr_params p)
  1307. {
  1308.   effadr dst = GetEA(p.dest, p.mask);
  1309.   ULONG data = GetFromEA(dst) & p.mask;
  1310.  
  1311.   ULONG cmask = 1 << mask2shift(p.mask);
  1312.   ULONG sign = data & cmask;
  1313.   regs.v = 0;
  1314.   regs.c = regs.x = data & 1;
  1315.   data = (data >> 1) | sign;
  1316.   regs.n = sign != 0;
  1317.   regs.z = (data & p.mask) == 0;
  1318.   StoreToEA(dst,data);
  1319. }
  1320.  
  1321. static instr_result INST_LSR1(const instr_params p)
  1322. {
  1323.   effadr dst = GetEA(p.dest, p.mask);
  1324.   ULONG data = GetFromEA(dst) & p.mask;
  1325.   int carry = data & 1;
  1326.   data >>= 1;
  1327.   setflags_logical(data, p.mask);
  1328.   regs.c = regs.x = carry;
  1329.   StoreToEA(dst,data);
  1330. }
  1331.  
  1332. static instr_result INST_LSL1(const instr_params p)
  1333. {
  1334.   effadr dst = GetEA(p.dest, p.mask);
  1335.   ULONG data = GetFromEA(dst) & p.mask;
  1336.  
  1337.   ULONG cmask = 1 << mask2shift(p.mask);
  1338.   ULONG carry = data & cmask;
  1339.   data <<= 1;
  1340.   setflags_logical(data,p.mask);
  1341.   regs.c = regs.x = carry != 0;
  1342.   StoreToEA(dst,data);
  1343. }
  1344.  
  1345. static instr_result INST_ROR1(const instr_params p)
  1346. {
  1347.   effadr dst = GetEA(p.dest, p.mask);
  1348.   ULONG data = GetFromEA(dst) & p.mask;
  1349.  
  1350.   ULONG cmask = 1 << mask2shift(p.mask);
  1351.   int carry = data & 1;
  1352.   data >>= 1;
  1353.   if (carry) data |= cmask;
  1354.   setflags_logical(data,p.mask);
  1355.   regs.c = carry;
  1356.   StoreToEA(dst,data);
  1357. }
  1358.  
  1359. static instr_result INST_ROL1(const instr_params p)
  1360. {
  1361.   effadr dst = GetEA(p.dest, p.mask);
  1362.   ULONG data = GetFromEA(dst) & p.mask;
  1363.  
  1364.   ULONG cmask = 1 << mask2shift(p.mask);
  1365.   ULONG carry = data & cmask;
  1366.  
  1367.   data <<= 1;
  1368.   if (carry) data |= 1;
  1369.   setflags_logical(data,p.mask);
  1370.   regs.c = carry != 0;
  1371.   StoreToEA(dst,data);
  1372. }
  1373.  
  1374. static instr_result INST_ROXR1(const instr_params p)
  1375. {
  1376.   effadr dst = GetEA(p.dest, p.mask);
  1377.   ULONG data = GetFromEA(dst) & p.mask;
  1378.  
  1379.   ULONG cmask = 1 << mask2shift(p.mask);
  1380.   int carry = data & 1;
  1381.   data >>= 1;
  1382.   if (regs.x) data |= cmask;
  1383.   setflags_logical(data,p.mask);
  1384.   regs.c = regs.x = carry;
  1385.   StoreToEA(dst,data);
  1386. }
  1387.  
  1388. static instr_result INST_ROXL1(const instr_params p)
  1389. {
  1390.   effadr dst = GetEA(p.dest, p.mask);
  1391.   ULONG data = GetFromEA(dst) & p.mask;
  1392.  
  1393.   ULONG cmask = 1 << mask2shift(p.mask);
  1394.   ULONG carry = data & cmask;
  1395.  
  1396.   data <<= 1;
  1397.   if (regs.x) data |= 1;
  1398.   
  1399.   setflags_logical(data,p.mask);
  1400.   regs.c = regs.x = carry != 0;
  1401.   StoreToEA(dst,data);
  1402. }
  1403.  
  1404. static instr_result INST_MOVECCREA(const instr_params p)
  1405. {
  1406.   INST_NIMP(p); 
  1407. }
  1408.  
  1409. static instr_result INST_MOVESREA(const instr_params p)
  1410. {
  1411.     effadr ea = GetEA(p.src, p.mask);
  1412.     MakeSR();
  1413.     StoreToEA(ea,regs.sr);
  1414. }
  1415.  
  1416. static instr_result INST_MOVEEACCR(const instr_params p)
  1417. {
  1418.     effadr ea = GetEA(p.src, p.mask);
  1419.     MakeSR();
  1420.     regs.sr &= 0xFF00;
  1421.     regs.sr |= GetFromEA(ea) & 0xFF;
  1422.     MakeFromSR();
  1423. }
  1424.  
  1425. static instr_result INST_MOVEEASR(const instr_params p)
  1426. {
  1427.     if ((p.mask != 0xff) && !regs.s) {
  1428.     m68k_setpc(m68k_getpc()-2);
  1429.     Exception(8);
  1430.     } else {
  1431.     effadr ea = GetEA(p.src, p.mask);
  1432.     regs.sr = GetFromEA(ea);
  1433.     MakeFromSR();
  1434.     }
  1435. }
  1436.  
  1437. static instr_result INST_ORSR(const instr_params p)
  1438. {
  1439.     if ((p.mask != 0xff) && !regs.s) {
  1440.     m68k_setpc(m68k_getpc()-2);
  1441.     Exception(8);
  1442.     } else {
  1443.     effadr ea = GetEA(p.src, p.mask);
  1444.     MakeSR();
  1445.     regs.sr |= GetFromEA(ea);
  1446.     MakeFromSR();
  1447.     }
  1448. }
  1449.  
  1450. static instr_result INST_EORSR(const instr_params p)
  1451. {
  1452.     if ((p.mask != 0xff) && !regs.s) {
  1453.       m68k_setpc(m68k_getpc()-2);
  1454.     Exception(8);
  1455.     } else {
  1456.     effadr ea = GetEA(p.src, p.mask);
  1457.     MakeSR();
  1458.     regs.sr ^= GetFromEA(ea);
  1459.     MakeFromSR();
  1460.     }
  1461. }
  1462.  
  1463. static instr_result INST_ANDSR(const instr_params p)
  1464. {
  1465.     if ((p.mask != 0xff) && !regs.s) {
  1466.     m68k_setpc(m68k_getpc()-2);
  1467.     Exception(8);
  1468.     } else {
  1469.     effadr ea = GetEA(p.src, p.mask);
  1470.     MakeSR();
  1471.     regs.sr &= GetFromEA(ea);
  1472.     MakeFromSR();
  1473.     }
  1474. }
  1475.  
  1476. static instr_result INST_MOVEMEARL(const instr_params p)
  1477. {
  1478.     int i;
  1479.     UWORD bitmask = nextiword();
  1480.     effadr ea = MGetEA(p.src, p.mask);
  1481.     
  1482.     for(i=0; i<8; i++) {
  1483.     if (bitmask & (1 << i)) {
  1484.         regs.d[i] = Extend(GetFromEA(ea), p.mask);
  1485.         ea.addr += mask2len(p.mask);
  1486.     }
  1487.     }
  1488.     for(i=0; i<8; i++) {
  1489.     if (bitmask & (1 << (i + 8))) {
  1490.         regs.a[i] = Extend(GetFromEA(ea),p.mask);
  1491.         ea.addr += mask2len(p.mask);
  1492.     }
  1493.     }
  1494.     MCompleteEAToRL(ea, p.src);
  1495. }
  1496.  
  1497. static instr_result INST_MOVEMRLEA(const instr_params p)
  1498. {
  1499.     UWORD bitmask = nextiword();
  1500.     effadr ea;
  1501.     int rd[8], ra[8], i, kludge;
  1502.     for(i=0;i<8;i++){
  1503.     rd[i] = regs.d[i]; ra[i] = regs.a[i];
  1504.     }
  1505.     ea = MGetEA(p.src, p.mask);
  1506.     kludge = (p.src.mode == Apdi) ? 15 : 0;
  1507.     MCompleteEAFromRL(&ea, p.src, p.mask, bitmask);
  1508.     for(i=0; i<8; i++) {
  1509.     if (bitmask & (1 << (i ^ kludge))) {
  1510.         StoreToEA(ea,rd[i]);
  1511.         ea.addr += mask2len(p.mask);
  1512.     }
  1513.     }
  1514.     for(i=0; i<8; i++) {
  1515.     if (bitmask & (1 << ((i + 8) ^ kludge))) {
  1516.         StoreToEA(ea,ra[i]);
  1517.         ea.addr += mask2len(p.mask);
  1518.     }
  1519.     }
  1520. }
  1521.  
  1522. static instr_result INST_MOVEAUSP(const instr_params p)
  1523. {
  1524.     effadr ea = GetEA(p.src,0xffffffff);
  1525.     if (regs.s) {
  1526.     regs.usp = GetFromEA(ea);
  1527.     } else {
  1528.     m68k_setpc(m68k_getpc()-2); Exception(8);
  1529.     }
  1530. }
  1531.  
  1532. static instr_result INST_MOVEUSPA(const instr_params p)
  1533. {
  1534.     effadr ea = GetEA(p.src,0xffffffff);
  1535.     if (regs.s) {
  1536.     StoreToEA(ea,regs.usp);
  1537.     } else {
  1538.     m68k_setpc(m68k_getpc()-2); Exception(8);
  1539.     }
  1540. }
  1541.  
  1542. static instr_result INST_LINEA(const instr_params p)
  1543. {
  1544.     m68k_setpc(m68k_getpc()-2);
  1545.     
  1546.     Exception(10);
  1547. }
  1548.  
  1549. static instr_result INST_LINEF(const instr_params p)
  1550. {
  1551.     m68k_setpc(m68k_getpc()-2);
  1552.     
  1553.     Exception(11);
  1554. }
  1555.  
  1556.  /*
  1557.   * debugging functions
  1558.   */
  1559.  
  1560. typedef struct {
  1561.   instr_func f;
  1562.   char *name;
  1563.   bool src,dest,spc;
  1564. } debug_entry;
  1565.  
  1566. static debug_entry debugtbl[] = {
  1567.   { &INST_OR,"OR",1,1,0 },
  1568.   { &INST_AND,"AND",1,1,0 },
  1569.   { &INST_EOR,"EOR",1,1,0 },
  1570.   { &INST_CMP,"CMP",1,1,0 },
  1571.   { &INST_ADD,"ADD",1,1,0 },
  1572.   { &INST_SUB,"SUB",1,1,0 },
  1573.   { &INST_ADDX,"ADDX",1,1,0 },
  1574.   { &INST_SUBX,"SUBX",1,1,0 },
  1575.  
  1576.   { &INST_ADDA,"ADDA",1,1,0 },
  1577.   { &INST_SUBA,"SUBA",1,1,0 },
  1578.   { &INST_CMPA,"CMPA",1,1,0 },
  1579.  
  1580.   { &INST_CHK,"CHK",1,1,0 },
  1581.  
  1582.   { &INST_EXGL,"EXG",1,1,0 },
  1583.  
  1584.   { &INST_LEA,"LEA",1,1,0 },
  1585.   { &INST_MOVE,"MOVE",1,1,0 },
  1586.   { &INST_MOVEA,"MOVEA",1,1,0 },
  1587.   { &INST_MOVEQ,"MOVEQ",1,1,0 },
  1588.   { &INST_BTST,"BTST",1,1,0 },
  1589.   { &INST_BCLR,"BCLR",1,1,0 },
  1590.   { &INST_BSET,"BSET",1,1,0 },
  1591.   { &INST_BCHG,"BCHG",1,1,0 },
  1592.   { &INST_NEG,"NEG",1,0,0 },
  1593.   { &INST_NEGX,"NEGX",1,0,0 },
  1594.   { &INST_NOT,"NOT",1,0,0 },
  1595.   { &INST_CLR,"CLR",1,0,0 },
  1596.   { &INST_TST,"TST",1,0,0 },
  1597.   { &INST_SWAP,"SWAP",1,0,0 },
  1598.   { &INST_EXTW,"EXT",1,0,0 },
  1599.   { &INST_EXTL,"EXT",1,0,0 },
  1600.   { &INST_Scc,"Scc",1,0,0 },
  1601.   { &INST_ABCD,"ABCD",1,1,0 },
  1602.   { &INST_SBCD,"SBCD",1,1,0 },
  1603.   { &INST_NBCD,"NBCD",1,1,0 },
  1604.   { &INST_NOP,"NOP",0,0,0 },
  1605.   { &INST_RESET,"RESET",0,0,0 },
  1606.   { &INST_STOP,"STOP",1,0,0 },
  1607.   { &INST_TRAPV,"TRAPV",1,0,0 },
  1608.   { &INST_TRAP,"TRAP",1,0,0 },
  1609.   { &INST_BSRB,"BSR",1,0,0 },
  1610.   { &INST_BccB,"Bcc",1,0,0 },
  1611.   { &INST_BSRW,"BSR",1,0,0 },
  1612.   { &INST_BccW,"Bcc",1,0,0 },
  1613.   { &INST_DBcc,"DBcc",1,0,10 },
  1614.   { &INST_JMP,"JMP",1,0,0 },
  1615.   { &INST_JSR,"JSR",1,0,0 },
  1616.   { &INST_RTE,"RTE",0,0,0 },
  1617.   { &INST_RTD,"RTD",0,0,0 },
  1618.   { &INST_RTS,"RTS",0,0,0 },
  1619.   { &INST_RTR,"RTR",0,0,0 },
  1620.   { &INST_LINK,"LINK",1,1,0 },
  1621.   { &INST_UNLK,"UNLK",1,0,0 },
  1622.   { &INST_MULU,"MULU",1,1,0 },
  1623.   { &INST_MULS,"MULS",1,1,0 },
  1624.   { &INST_DIVU, "DIVU",1,1,0 },
  1625.   { &INST_DIVS,"DIVS",1,1,0 },
  1626.   { &INST_ASR,"ASR",1,1,0 },
  1627.   { &INST_ASL,"ASL",1,1,0 },
  1628.   { &INST_LSR,"LSR",1,1,0 },
  1629.   { &INST_LSL,"LSL",1,1,0 },
  1630.   { &INST_ROR,"ROR",1,1,0 },
  1631.   { &INST_ROL,"ROL",1,1,0 },
  1632.   { &INST_ROXR,"ROXR",1,1,0 },
  1633.   { &INST_ROXL,"ROXL",1,1,0 },
  1634.   { &INST_ASR1,"ASR",1,0,0 },
  1635.   { &INST_ASL1,"ASL",1,0,0 },
  1636.   { &INST_LSR1,"LSR",1,0,0 },
  1637.   { &INST_LSL1,"LSL",1,0,0 },
  1638.   { &INST_ROR1,"ROR",1,0,0 },
  1639.   { &INST_ROL1,"ROL",1,0,0 },
  1640.   { &INST_ROXR1,"ROXR",1,0,0 },
  1641.   { &INST_ROXL1,"ROXL",1,0,0 },
  1642.   { &INST_MOVECCREA,"MOVE CCR,",1,0,0 },
  1643.   { &INST_MOVESREA,"MOVE SR,",1,0,0 },
  1644.   { &INST_MOVEEACCR,"MOVE2CCR",1,0,0 },
  1645.   { &INST_MOVEEASR,"MOVE2SR",1,0,0 },
  1646.   { &INST_MOVEMEARL,"MOVEM",1,0,9 },
  1647.   { &INST_MOVEMRLEA,"MOVEM",1,0,5 },
  1648.   { &INST_MOVEAUSP,"MOVE2USP",1,1,0 },
  1649.   { &INST_MOVEUSPA,"MOVE USP,",1,1,0 },
  1650.  
  1651.   { &INST_ORSR,"ORSR",1,0,0 },
  1652.   { &INST_ANDSR,"ANDSR",1,0,0 },
  1653.   { &INST_EORSR,"EORSR",1,0,0 },
  1654.  
  1655.   { &INST_LINEA,"LINEA",0,0,0 },
  1656.   { &INST_LINEF,"LINEF",0,0,0 },
  1657.   { &INST_ILLG,"ILLEGAL",0,0,0 },
  1658.   { &INST_NIMP,"NOT IMPLEMENTED",0,0,0 },
  1659.   { NULL,NULL,0,0,0 }
  1660. };
  1661.  
  1662. static char* ccnames[] =
  1663. { "T ","F ","HI","LS","CC","CS","NE","EQ",
  1664.   "VC","VS","PL","MI","GE","LT","GT","LE" };
  1665.  
  1666. void MC68000_reset(void)
  1667. {
  1668.     instr_params p;
  1669.     
  1670.     regs.a[7] = get_long(0x00f80000);
  1671.     m68k_setpc(get_long(0x00f80004));
  1672.     regs.s = 1;
  1673.     regs.stopped = 0;
  1674.     regs.t = 0;
  1675.     specialflags = 0;
  1676.     regs.intmask = 7;
  1677.     INST_RESET(p);
  1678. }
  1679.  
  1680. void op_illg(UWORD opcode)
  1681. {
  1682.     if (opcode == 0xF00D && ((m68k_getpc() & 0xF80000) == 0xF80000)) {
  1683.     /* This is from the dummy Kickstart replacement */
  1684.     ersatz_perform (nextiword ());
  1685.     return;
  1686.     }
  1687.     regs.pc_p--;
  1688.     if ((opcode & 0xF000) == 0xF000) {    
  1689.         Exception(0xB);
  1690.     return;
  1691.     }
  1692.     if ((opcode & 0xF000) == 0xA000) {
  1693.         Exception(0xA);
  1694.     return;
  1695.     }
  1696.     fprintf(stderr, "Illegal instruction: %04x\n", opcode);
  1697.     Exception(4);
  1698. }
  1699.  
  1700. static int n_insns=0, n_spcinsns=0;
  1701.  
  1702. static __inline__ void do_hardware(void)
  1703. {
  1704.     if (specialflags & SPCFLAG_BLIT) {
  1705.     do_blitter();
  1706. #ifdef NO_FAST_BLITTER
  1707.     do_blitter();
  1708.     do_blitter();
  1709.     do_blitter();
  1710. #endif
  1711.     }
  1712.     if (specialflags & SPCFLAG_DISK) {
  1713.     do_disk(); /* This is not critical. Four calls make disk */
  1714.     do_disk(); /* loading quite fast. */
  1715.     do_disk();
  1716.     do_disk();
  1717.     }
  1718. }
  1719.  
  1720. void MC68000_run(void)
  1721. {
  1722.     for(;;) {
  1723.     UWORD opcode;
  1724.     /* assert (!regs.stopped && !(specialflags & SPCFLAG_STOP)); */
  1725.     opcode = nextiword();
  1726. #ifdef COUNT_INSTRS
  1727.     instrcount[opcode]++;
  1728. #endif
  1729.     (*cpufunctbl[opcode])(opcode);
  1730. #ifndef NO_EXCEPTION_3
  1731.     if (buserr) {
  1732.         Exception(3);
  1733.         buserr = false;
  1734.     }
  1735. #endif
  1736.     /*n_insns++;*/
  1737.     do_cycles();    
  1738.     if (specialflags) {
  1739.         /*n_spcinsns++;*/
  1740.         while (specialflags & SPCFLAG_STOP) {
  1741.         do_cycles();
  1742.         do_hardware();
  1743.         if (specialflags & (SPCFLAG_INT | SPCFLAG_DOINT)){
  1744.             int intr = intlev();
  1745.             specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
  1746.             specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
  1747.             if (intr != -1 && intr > regs.intmask) {
  1748.             Interrupt(intr);
  1749.             regs.stopped = 0;
  1750.             specialflags &= ~SPCFLAG_STOP;
  1751.             }        
  1752.         }        
  1753.         }
  1754.         if (specialflags & SPCFLAG_DOTRACE) {
  1755.         Exception(9);
  1756.         }
  1757.         if (specialflags & SPCFLAG_TRACE) {
  1758.         specialflags &= ~SPCFLAG_TRACE;
  1759.         specialflags |= SPCFLAG_DOTRACE;
  1760.         }
  1761. #ifdef WANT_SLOW_MULTIPLY
  1762.         /* Kludge for Hardwired demo. The guys who wrote it should be
  1763.          * mutilated. */
  1764.         if (specialflags & SPCFLAG_EXTRA_CYCLES) {
  1765.         do_cycles ();
  1766.         do_cycles ();
  1767.         do_cycles ();
  1768.         do_cycles ();
  1769.         specialflags &= ~SPCFLAG_EXTRA_CYCLES;
  1770.         }
  1771. #endif
  1772.         do_hardware();
  1773.         
  1774.         if (specialflags & SPCFLAG_DOINT) {
  1775.         int intr = intlev();
  1776.         specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
  1777.         if (intr != -1 && intr > regs.intmask) {
  1778.             Interrupt(intr);
  1779.             regs.stopped = 0;
  1780.         }        
  1781.         }
  1782.         if (specialflags & SPCFLAG_INT) {
  1783.         specialflags &= ~SPCFLAG_INT;
  1784.         specialflags |= SPCFLAG_DOINT;
  1785.         }
  1786.         if (specialflags & SPCFLAG_BRK) {        
  1787.         specialflags &= ~SPCFLAG_BRK;
  1788.         return;        
  1789.         }
  1790.     }
  1791.     }
  1792. }
  1793.  
  1794. void MC68000_step(void)
  1795. {
  1796.     specialflags |= SPCFLAG_BRK;
  1797.     MC68000_run();
  1798. }
  1799.  
  1800. void MC68000_skip(CPTR nextpc)
  1801. {
  1802.     broken_in = false;
  1803.     specialflags |= SPCFLAG_BRK;
  1804.     do {
  1805.     MC68000_step();
  1806.     } while (nextpc != m68k_getpc() && !broken_in);
  1807. }
  1808.  
  1809. void MC68000_disasm(CPTR addr, CPTR *nextpc, int cnt)
  1810. {
  1811.     CPTR pc = m68k_getpc();
  1812.     m68k_setpc(addr);
  1813.     for (;cnt--;){
  1814.     char instrname[20],*ccpt;
  1815.     int opwords;
  1816.     UWORD opcode;
  1817.     I_dec_tab_entry dtentry;
  1818.     debug_entry *dp;
  1819.     UWORD special = 0;
  1820.  
  1821.     printf("%08lx: ", m68k_getpc());
  1822.     for(opwords = 0; opwords < 5; opwords++){
  1823.         printf("%04x ", get_word(m68k_getpc() + opwords*2));
  1824.     }
  1825.     
  1826.     opcode = nextiword();
  1827.     if (cpufunctbl[opcode] == op_illg) {
  1828.         opcode = 0x4AFC;
  1829.     }
  1830.     
  1831.     dtentry = instr_dectab[opcode];
  1832.     
  1833.     for (dp = debugtbl;dp->f && dp->f != dtentry.execfunc;dp++)
  1834.         ;
  1835.     
  1836.     strcpy(instrname,dp->name);
  1837.     ccpt = strstr(instrname,"cc");
  1838.     if (ccpt != 0) {
  1839.         strncpy(ccpt,ccnames[dtentry.params.dest.reg],2);
  1840.     }
  1841.     printf("%s", instrname);
  1842.     switch(dtentry.params.mask){
  1843.      case 0xff: printf(".B "); break;
  1844.      case 0xffff: printf(".W "); break;
  1845.      case 0xffffffff: printf(".L "); break;
  1846.     }
  1847.  
  1848.     if (dp->spc & 1) {
  1849.         special = nextiword();
  1850.     }
  1851.     if (dp->spc & 4) {
  1852.         printf("#$%04x,", special);
  1853.     }
  1854.     if (dp->src) {
  1855.         ShowEA(dtentry.params.src,dtentry.params.mask);
  1856.     }
  1857.     if (dp->src && dp->dest) printf(",");
  1858.     if (dp->dest) {
  1859.         ShowEA(dtentry.params.dest,dtentry.params.mask);
  1860.     }
  1861.     if (dp->spc & 2) {
  1862.         special = nextiword();
  1863.     }
  1864.     if (dp->spc & 8) {
  1865.         printf(",#$%04x", special);
  1866.     }
  1867.     if (ccpt != 0) {
  1868.         if (cctrue(dtentry.params.dest.reg)) 
  1869.         printf(" (TRUE)");
  1870.         else 
  1871.         printf(" (FALSE)");
  1872.     }
  1873.     printf("\n");
  1874.     }
  1875.     *nextpc = m68k_getpc();
  1876.     m68k_setpc(pc);
  1877. }
  1878.  
  1879. void MC68000_dumpstate(CPTR *nextpc)
  1880. {
  1881.     int i;
  1882.     for(i = 0; i < 8; i++){
  1883.     printf("D%d: %08lx ", i, regs.d[i]);
  1884.     if ((i & 3) == 3) printf("\n");
  1885.     }
  1886.     for(i=0;i<8;i++){
  1887.     printf("A%d: %08lx ", i, regs.a[i]);
  1888.     if ((i & 3) == 3) printf("\n");
  1889.     }
  1890.     printf ("T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d\n", regs.t, regs.s, 
  1891.         regs.x, regs.n, regs.z, regs.v, regs.c, regs.intmask);
  1892.     MC68000_disasm(m68k_getpc(), nextpc, 1);
  1893.     printf("next PC: %08lx\n", *nextpc);
  1894. }
  1895.  
  1896.  /* 
  1897.   * GenerateDecTab() creates the instruction decode table.
  1898.   * FIXME: This should generate all legal instructions, but some illegal ones
  1899.   * will not be directed to INST_ILLG. On an accidental execution, a function
  1900.   * like GetEA() may call abort().
  1901.   * This is no longer a big problem, as the other CPU emulator is used now
  1902.   * and the disassembler has more error checks.
  1903.   */
  1904.  
  1905. static void GenerateDecTab(void)
  1906. {
  1907.     int offset;
  1908.     long int opcode;
  1909.     for(opcode = 0; opcode < 65536; opcode++){
  1910.     int r1 = (opcode & 0x0E00) >> 9;
  1911.     int m1 = (opcode & 0x01C0) >> 6;
  1912.     int m2 = (opcode & 0x0038) >> 3;
  1913.     int r2 = (opcode & 0x0007);
  1914.     int x  = (m1 & 4) >> 2;
  1915.     int sz = (m1 & 3);
  1916.     addr_mode am1, am2;
  1917.     I_dec_tab_entry entry;
  1918.     set_addr_mode(&am1, m1, r1);
  1919.     set_addr_mode(&am2, m2, r2);
  1920.     
  1921.     switch(opcode & 0xF000) {
  1922.      case 0x0000: 
  1923.         if (x) { 
  1924.         if (am2.mode == Dreg || am2.mode == Aind ||
  1925.             am2.mode == Aipi || am2.mode == Apdi ||
  1926.             am2.mode == Ad16 || am2.mode == Ad8r ||
  1927.             am2.mode == absw || am2.mode == absl) {
  1928.             switch(sz){ 
  1929.              case 0:
  1930.             entry.execfunc = &INST_BTST;
  1931.             break;
  1932.              case 1:
  1933.             entry.execfunc = &INST_BCHG;
  1934.             break;
  1935.              case 2:
  1936.             entry.execfunc = &INST_BCLR;
  1937.             break;
  1938.              case 3:
  1939.             entry.execfunc = &INST_BSET;
  1940.             break;
  1941.             }
  1942.             entry.params.mask = 0xffffffff;
  1943.             am1 = am2;
  1944.             am2.mode = Dreg; am2.reg = r1;
  1945.         } else {
  1946.             entry.execfunc = &INST_NIMP; /* MOVEP */
  1947.         }
  1948.         } else {
  1949.         am1.mode = imm;
  1950.         if (sz == 3) {
  1951.             switch(r1){
  1952.              case 0:
  1953.              case 1:
  1954.              case 2:
  1955.              case 6:
  1956.              case 7:
  1957.             entry.execfunc = &INST_ILLG;
  1958.             break;
  1959.              case 3:
  1960.             entry.execfunc = &INST_NIMP; /* RTM */
  1961.             break;
  1962.              case 4:
  1963.             entry.execfunc = &INST_BSET;
  1964.             am1 = am2;
  1965.             am2.mode = imm;
  1966.             entry.params.mask = 0xffff;
  1967.             break;
  1968.              case 5:
  1969.             entry.execfunc = &INST_NIMP; /* CAS */
  1970.             break;
  1971.             }
  1972.         } else {
  1973.             entry.params.mask = sizemask(sz);
  1974.             switch(r1){
  1975.              case 0:
  1976.             if (am2.mode == imm) 
  1977.                 entry.execfunc = &INST_ORSR;
  1978.             else
  1979.                 entry.execfunc = &INST_OR;
  1980.             break;
  1981.              case 1:
  1982.             if (am2.mode == imm) 
  1983.                 entry.execfunc = &INST_ANDSR;
  1984.             else
  1985.                 entry.execfunc = &INST_AND;
  1986.             break;
  1987.              case 2:
  1988.             entry.execfunc = &INST_SUB;
  1989.             break;
  1990.              case 3:
  1991.             entry.execfunc = &INST_ADD;
  1992.             break;
  1993.              case 4:
  1994.             switch(sz){
  1995.              case 0: entry.execfunc = &INST_BTST; break;
  1996.              case 1: entry.execfunc = &INST_BCHG; break;
  1997.              case 2: entry.execfunc = &INST_BCLR; break;
  1998.             }
  1999.             entry.params.mask = 0xffff;
  2000.             break;
  2001.              case 5:
  2002.             if (am2.mode == imm) 
  2003.                 entry.execfunc = &INST_EORSR;
  2004.             else
  2005.                 entry.execfunc = &INST_EOR;
  2006.             break;
  2007.              case 6:
  2008.             entry.execfunc = &INST_CMP;
  2009.             break;
  2010.              case 7:
  2011.             entry.execfunc = &INST_NIMP; /* MOVES */
  2012.             break;
  2013.             }
  2014.             am1 = am2; am2.mode = imm;
  2015.         }
  2016.         }
  2017.         break; 
  2018.      case 0x1000:
  2019.         switch(am1.mode) {
  2020.          case Areg: case imm: case imm3: case ill2: case ill3:
  2021.         entry.execfunc = &INST_ILLG; /* MOVEA.B ??? */
  2022.         break;
  2023.          default:
  2024.         entry.execfunc = &INST_MOVE; /* MOVE.B */
  2025.         break;
  2026.         }
  2027.         entry.params.mask = 0xff;
  2028.         break; 
  2029.      case 0x2000:
  2030.         switch(am1.mode) {
  2031.          case Areg:
  2032.         entry.execfunc = &INST_MOVEA; /* MOVEA.L */
  2033.         break;
  2034.          case imm: case imm3: case ill2: case ill3:
  2035.         entry.execfunc = &INST_ILLG;
  2036.         break;
  2037.          default:
  2038.         entry.execfunc = &INST_MOVE; /* MOVE.L */
  2039.         break;
  2040.         }
  2041.         entry.params.mask = 0xffffffff; 
  2042.         break; 
  2043.      case 0x3000: 
  2044.         switch(am1.mode) {
  2045.          case Areg:
  2046.         entry.execfunc = &INST_MOVEA; /* MOVEA.W */
  2047.         break;
  2048.          case imm: case imm3: case ill2: case ill3:
  2049.         entry.execfunc = &INST_ILLG;
  2050.         break;
  2051.          default:
  2052.         entry.execfunc = &INST_MOVE; /* MOVE.W */
  2053.         break;
  2054.         }
  2055.         entry.params.mask = 0xffff;
  2056.         break; 
  2057.      case 0x4000: 
  2058.         if (x){
  2059.         switch(sz){
  2060.          case 0:
  2061.             entry.execfunc = &INST_CHK;
  2062.             entry.params.mask = 0xffffffff;
  2063.             am1.mode = Dreg; am1.reg = r1;
  2064.             break;
  2065.          case 1:
  2066.             entry.execfunc = &INST_ILLG;
  2067.             break;
  2068.          case 2:
  2069.             entry.execfunc = &INST_CHK;
  2070.             entry.params.mask = 0xffff;
  2071.             am1.mode = Dreg; am1.reg = r1;
  2072.             break;
  2073.          case 3:
  2074.             if (am2.mode == Dreg) {
  2075.             entry.execfunc = &INST_NIMP; /* EXTB.L */
  2076.             } else {
  2077.             entry.execfunc = &INST_LEA;
  2078.             entry.params.mask = 0xffffffff;
  2079.             am1.mode = Areg; am1.reg = r1;
  2080.             }
  2081.             break;
  2082.         }
  2083.         } else {
  2084.         switch(sz){
  2085.          case 0:
  2086.             switch(r1){
  2087.              case 0:
  2088.             entry.execfunc = &INST_NEG;
  2089.             entry.params.mask = 0xff;
  2090.             break;
  2091.              case 1:
  2092.             entry.execfunc = &INST_CLR;
  2093.             entry.params.mask = 0xff;
  2094.             break;
  2095.              case 2:
  2096.             entry.execfunc = &INST_NEG;
  2097.             entry.params.mask = 0xff;
  2098.             break;
  2099.              case 3:
  2100.             entry.execfunc = &INST_NOT;
  2101.             entry.params.mask = 0xff;
  2102.             break;
  2103.              case 4:
  2104.             if (am2.mode == Areg) {
  2105.                 entry.execfunc = &INST_LINK; /* this is from 020 upwards */
  2106.                 entry.params.mask = 0xffffffff;
  2107.                 am1.mode = imm;
  2108.             } else {
  2109.                 entry.execfunc = &INST_NBCD;
  2110.                 entry.params.mask = 0xff;
  2111.             }
  2112.             break;
  2113.              case 5:
  2114.             entry.execfunc = &INST_TST;
  2115.             entry.params.mask = 0xff;
  2116.             break;
  2117.              case 6:
  2118.             entry.execfunc = &INST_NIMP; /* MUL[US].L */
  2119.             break;
  2120.              case 7:
  2121.             entry.execfunc = &INST_ILLG;
  2122.             break;
  2123.             }
  2124.             break;
  2125.          case 1:
  2126.             switch(r1){
  2127.              case 0:
  2128.             entry.execfunc = &INST_NEG;
  2129.             entry.params.mask = 0xffff;
  2130.             break;
  2131.              case 1:
  2132.             entry.execfunc = &INST_CLR;
  2133.             entry.params.mask = 0xffff;
  2134.             break;
  2135.              case 2:
  2136.             entry.execfunc = &INST_NEG;
  2137.             entry.params.mask = 0xffff;
  2138.             break;
  2139.              case 3:
  2140.             entry.execfunc = &INST_NOT;
  2141.             entry.params.mask = 0xffff;
  2142.             break;
  2143.              case 4:
  2144.             if (am2.mode == Dreg) {
  2145.                 entry.execfunc = &INST_SWAP;
  2146.                 entry.params.mask = 0xffffffff;
  2147.             } else {
  2148.                 entry.execfunc = &INST_LEA; /* PEA == LEA ea,-(A7) */
  2149.                 entry.params.mask = 0xffffffff;
  2150.                 am1.mode = Apdi;
  2151.                 am1.reg = 7;
  2152.             }
  2153.             break;
  2154.              case 5:
  2155.             entry.execfunc = &INST_TST;
  2156.             entry.params.mask = 0xffff;
  2157.             break;
  2158.              case 6:
  2159.             entry.execfunc = &INST_NIMP; /* DIV[US]{L}.L */
  2160.             break;
  2161.              case 7:
  2162.             switch(am2.mode){
  2163.              case Areg: case Dreg:
  2164.                 entry.execfunc = &INST_TRAP;
  2165.                 am2.mode = imm3;
  2166.                 am2.reg = opcode & 0xf;
  2167.                 break;
  2168.              case Aind:
  2169.                 entry.execfunc = &INST_LINK;
  2170.                 am1.mode = imm;
  2171.                 am2.mode = Areg;
  2172.                 entry.params.mask = 0xffff;
  2173.                 break;
  2174.              case Aipi:
  2175.                 entry.execfunc = &INST_UNLK;
  2176.                 am2.mode = Areg;
  2177.                 break;
  2178.              case Apdi:
  2179.                 entry.execfunc = &INST_MOVEAUSP;
  2180.                 am2.mode = Areg;
  2181.                 break;
  2182.              case Ad16:
  2183.                 entry.execfunc = &INST_MOVEUSPA;
  2184.                 am2.mode = Areg;
  2185.                 break;
  2186.              case Ad8r:
  2187.                 am2.mode = imm;
  2188.                 switch(am2.reg){
  2189.                  case 0: entry.execfunc = &INST_RESET; break;
  2190.                  case 1: entry.execfunc = &INST_NOP; break;
  2191.                  case 2: entry.execfunc = &INST_STOP; break;
  2192.                  case 3: entry.execfunc = &INST_RTE; break;
  2193.                  case 4: entry.execfunc = &INST_RTD; break;
  2194.                  case 5: entry.execfunc = &INST_RTS; break;
  2195.                  case 6: entry.execfunc = &INST_TRAPV; break;
  2196.                  case 7: entry.execfunc = &INST_RTR; break;
  2197.                 }
  2198.                 break;
  2199.              case absw: case absl: case PC16: case PC8r: case imm:
  2200.              case imm3: case ill2: case ill3:
  2201.                 entry.execfunc = &INST_ILLG;
  2202.                 break;
  2203.             }
  2204.             }
  2205.             break;
  2206.          case 2:
  2207.             switch(r1){
  2208.              case 0:
  2209.             entry.execfunc = &INST_NEG;
  2210.             entry.params.mask = 0xffffffff;
  2211.             break;
  2212.              case 1:
  2213.             entry.execfunc = &INST_CLR;
  2214.             entry.params.mask = 0xffffffff;
  2215.             break;
  2216.              case 2:
  2217.             entry.execfunc = &INST_NEG;
  2218.             entry.params.mask = 0xffffffff;
  2219.             break;
  2220.              case 3:
  2221.             entry.execfunc = &INST_NOT;
  2222.             entry.params.mask = 0xffffffff;
  2223.             break;
  2224.              case 4:
  2225.             entry.params.mask = 0xffff;
  2226.             if (am2.mode == Dreg) {
  2227.                 entry.execfunc = &INST_EXTW;
  2228.             } else {
  2229.                 entry.execfunc = &INST_MOVEMRLEA;
  2230.             }
  2231.             break;
  2232.              case 5:
  2233.             entry.execfunc = &INST_TST;
  2234.             entry.params.mask = 0xffffffff;
  2235.             break;
  2236.              case 6:
  2237.             entry.params.mask =0xffff;
  2238.             entry.execfunc = &INST_MOVEMEARL;
  2239.             break;
  2240.              case 7:
  2241.             entry.params.mask =0xffffffff;
  2242.             if (am2.mode == imm) {
  2243.                 entry.execfunc = &INST_ILLG;
  2244.             } else {
  2245.                 entry.execfunc = &INST_JSR;
  2246.             }
  2247.             break;
  2248.             }
  2249.             break;
  2250.          case 3:
  2251.             entry.params.mask = 0xffff;
  2252.             switch(r1){
  2253.              case 0:
  2254.             entry.execfunc = &INST_MOVESREA;
  2255.             break;
  2256.              case 1:
  2257.             entry.execfunc = &INST_MOVECCREA;
  2258.             break;
  2259.              case 2:
  2260.             entry.execfunc = &INST_MOVEEACCR;
  2261.             break;
  2262.              case 3:
  2263.             entry.execfunc = &INST_MOVEEASR;
  2264.             break;
  2265.              case 4:
  2266.             entry.params.mask = 0xffffffff;
  2267.             if (am2.mode == Dreg) {
  2268.                 entry.execfunc = &INST_EXTL;
  2269.             } else {
  2270.                 entry.execfunc = &INST_MOVEMRLEA;
  2271.             }
  2272.             break;
  2273.              case 5:
  2274.             entry.execfunc = &INST_NIMP; /* TAS.B */
  2275.             break;
  2276.              case 6:
  2277.             entry.params.mask =0xffffffff;
  2278.             entry.execfunc = &INST_MOVEMEARL;
  2279.             break;
  2280.              case 7:
  2281.             entry.params.mask =0xffffffff;
  2282.             if (am2.mode == imm) {
  2283.                 entry.execfunc = &INST_ILLG;
  2284.             } else {
  2285.                 entry.execfunc = &INST_JMP;
  2286.             }
  2287.             break;
  2288.             }
  2289.             break;      
  2290.         }
  2291.         }
  2292.         break; 
  2293.      case 0x5000:
  2294.         switch(sz){
  2295.          case 0: case 1: case 2:
  2296.         entry.params.mask = sizemask(sz);
  2297.         if (x) {
  2298.             if (am2.mode == Areg) 
  2299.             entry.execfunc = &INST_SUBA/*Q*/;
  2300.             else
  2301.             entry.execfunc = &INST_SUB/*Q*/;
  2302.             
  2303.         } else {
  2304.             if (am2.mode == Areg)
  2305.             entry.execfunc = &INST_ADDA/*Q*/;
  2306.             else
  2307.             entry.execfunc = &INST_ADD/*Q*/;
  2308.         }
  2309.         am1 = am2; am2.mode = imm3; am2.reg = r1 ? r1 : 8;
  2310.         break;
  2311.          case 3:
  2312.         if (am2.mode == Areg) {
  2313.             entry.params.mask = 0xffff; 
  2314.             entry.execfunc = &INST_DBcc;
  2315.             am2.mode = Dreg;
  2316.         } else {
  2317.             entry.params.mask = 0xff;
  2318.             entry.execfunc = &INST_Scc;
  2319.         }
  2320.         am1.mode = imm3;
  2321.         am1.reg = (opcode & 0xf00) >> 8;
  2322.         }
  2323.         break; 
  2324.      case 0x6000:
  2325.         offset = opcode & 0xff;
  2326.         if (x == 1 && r1 == 0) {
  2327.         if (offset == 0) {
  2328.             entry.execfunc = &INST_BSRW;
  2329.             entry.params.mask = 0xffff;
  2330.             am2.mode = imm;
  2331.         } else {
  2332.             entry.execfunc = &INST_BSRB;
  2333.             entry.params.mask = 0xff;
  2334.             am2.mode = imm3; am2.reg = opcode & 0xff;
  2335.         }
  2336.         } else {
  2337.         if (offset == 0) {
  2338.             entry.execfunc = &INST_BccW;
  2339.             entry.params.mask = 0xffff;
  2340.             am2.mode = imm;
  2341.         } else {
  2342.             entry.execfunc = &INST_BccB;
  2343.             entry.params.mask = 0xff;
  2344.             am2.mode = imm3; am2.reg = opcode & 0xff;
  2345.         }
  2346.         }
  2347.         am1.reg = (opcode & 0xf00) >> 8;
  2348.         break;
  2349.      case 0x7000: 
  2350.         if (x) {
  2351.         entry.execfunc = &INST_ILLG;
  2352.         } else {
  2353.         entry.execfunc = &INST_MOVEQ;
  2354.         am1.mode = Dreg; am1.reg = r1; entry.params.mask = 0xffffffff;
  2355.         am2.mode = imm3; am2.reg = opcode & 0xff;
  2356.         }
  2357.         break; 
  2358.      case 0x8000: 
  2359.         if (x) {
  2360.         switch(sz) {
  2361.          case 0: case 1: case 2:
  2362.             entry.params.mask = sizemask(sz);
  2363.             switch (am2.mode) {
  2364.              case Dreg:
  2365.             if (sz != 0) {
  2366.                 entry.execfunc = &INST_NIMP; /* PACK, UNPK */
  2367.             } else {
  2368.                 entry.execfunc = &INST_SBCD;
  2369.                 entry.params.mask = 0xff;
  2370.                 am1.mode = Dreg;
  2371.                 am1.reg = r1;
  2372.             }
  2373.             break;
  2374.              case Areg:
  2375.             if (sz != 0) {
  2376.                 entry.execfunc = &INST_NIMP; /* PACK, UNPK */
  2377.             } else {
  2378.                 entry.execfunc = &INST_SBCD;
  2379.                 entry.params.mask = 0xff;
  2380.                 am1.mode = am2.mode = Apdi;
  2381.                 am1.reg = r1;
  2382.             }
  2383.             break;
  2384.              default:
  2385.             entry.execfunc = &INST_OR;
  2386.             am1 = am2; am2.mode = Dreg; am2.reg = r1;
  2387.             break;
  2388.             }
  2389.             break;
  2390.          case 3:
  2391.             entry.execfunc = &INST_DIVS;
  2392.             entry.params.mask = 0xffff;
  2393.             am1.mode = Dreg; am1.reg = r1;
  2394.             break;
  2395.         }
  2396.         } else {
  2397.         am1.mode = Dreg; am1.reg = r1;
  2398.         switch(sz) {
  2399.          case 0: case 1: case 2:
  2400.             entry.execfunc = &INST_OR;
  2401.             entry.params.mask = sizemask(sz);
  2402.             break;
  2403.          case 3:
  2404.             entry.execfunc = &INST_DIVU;
  2405.             entry.params.mask = 0xffff;
  2406.             break;
  2407.         }
  2408.         }
  2409.         break; 
  2410.      case 0x9000:
  2411.         if (sz == 3) {
  2412.         entry.execfunc = &INST_SUBA;
  2413.         entry.params.mask = x ? 0xffffffff : 0xffff;
  2414.         am1.mode = Areg; am1.reg = r1;
  2415.         } else {
  2416.         entry.execfunc = &INST_SUB;
  2417.         entry.params.mask = sizemask(sz);
  2418.         if (x) {
  2419.             switch(am2.mode) {
  2420.              case Dreg:
  2421.             entry.execfunc = &INST_SUBX;
  2422.             am1.mode = Dreg;
  2423.             am1.reg = r1;
  2424.             break;
  2425.              case Areg:
  2426.             entry.execfunc = &INST_SUBX;
  2427.             am1.mode = am2.mode = Apdi;
  2428.             am1.reg = r1;
  2429.             break;
  2430.              default:
  2431.             am1 = am2;
  2432.             am2.mode = Dreg;
  2433.             am2.reg = r1;
  2434.             break;
  2435.             }
  2436.         } else {
  2437.             am1.mode = Dreg;
  2438.             am1.reg = r1;
  2439.         }    
  2440.         }
  2441.         break; 
  2442.      case 0xA000: 
  2443.         entry.execfunc = &INST_LINEA;
  2444.         break; 
  2445.      case 0xB000:
  2446.         if (sz == 3) {
  2447.         entry.execfunc = &INST_CMPA;
  2448.         entry.params.mask = x ? 0xffffffff : 0xffff;
  2449.         am1.mode = Areg; am1.reg = r1;
  2450.         } else {
  2451.         entry.params.mask = sizemask(sz);
  2452.         am1.mode = Dreg; am1.reg = r1;
  2453.         if (x) {
  2454.             if (am2.mode == Areg){
  2455.             am1.mode = am2.mode = Aipi;
  2456.             am1.reg = r1;
  2457.             entry.execfunc = &INST_CMP/*M*/;
  2458.             } else {
  2459.             entry.execfunc = &INST_EOR;
  2460.             am1 = am2; am2.mode = Dreg; am2.reg = r1;
  2461.             }
  2462.         } else {
  2463.             entry.execfunc = &INST_CMP;
  2464.         }
  2465.         }
  2466.         break; 
  2467.      case 0xC000: 
  2468.         if (x) {
  2469.         switch(sz) {
  2470.          case 0: case 1: case 2:
  2471.             entry.params.mask = sizemask(sz);
  2472.             switch (am2.mode) {
  2473.              case Dreg:
  2474.             switch(sz) {
  2475.              case 2:
  2476.                 entry.execfunc = &INST_ILLG;
  2477.                 break;
  2478.              case 1:
  2479.                 entry.execfunc = &INST_EXGL;
  2480.                 entry.params.mask = 0xffffffff;
  2481.                 am1 = am2;
  2482.                 am2.mode = Dreg; am2.reg = r1;
  2483.                 break;
  2484.              case 0:
  2485.                 entry.execfunc = &INST_ABCD;
  2486.                 entry.params.mask = 0xff;
  2487.                 am1.mode = Dreg; am1.reg = r1;
  2488.                 break;
  2489.             }
  2490.             break;
  2491.              case Areg:
  2492.             switch(sz) {
  2493.              case 2:
  2494.                 entry.execfunc = &INST_EXGL;
  2495.                 entry.params.mask = 0xffffffff;
  2496.                 am1 = am2;
  2497.                 am2.mode = Dreg; am2.reg = r1;
  2498.                 break;
  2499.              case 1:
  2500.                 entry.execfunc = &INST_EXGL;
  2501.                 entry.params.mask = 0xffffffff;
  2502.                 am1 = am2;
  2503.                 am2.mode = Areg; am2.reg = r1;
  2504.                 break;
  2505.              case 0:
  2506.                 entry.execfunc = &INST_ABCD;
  2507.                 entry.params.mask = 0xff;
  2508.                 am1.mode = am2.mode = Apdi;
  2509.                 am1.reg = r1;
  2510.                 break;
  2511.             }
  2512.             break;
  2513.              default:
  2514.             entry.execfunc = &INST_AND;
  2515.             am1 = am2;
  2516.             am2.mode = Dreg; am2.reg = r1;
  2517.             break;
  2518.             }
  2519.             break;
  2520.          case 3:
  2521.             entry.execfunc = &INST_MULS;
  2522.             entry.params.mask = 0xffff;
  2523.             am1.mode = Dreg; am1.reg = r1;
  2524.             break;
  2525.         }
  2526.         } else {
  2527.         am1.mode = Dreg; am1.reg = r1;
  2528.         switch(sz) {
  2529.          case 0: case 1: case 2:
  2530.             entry.execfunc = &INST_AND;
  2531.             entry.params.mask = sizemask(sz);
  2532.             break;
  2533.          case 3:
  2534.             entry.execfunc = &INST_MULU;
  2535.             entry.params.mask = 0xffff;
  2536.             break;
  2537.         }
  2538.         }
  2539.         break; 
  2540.      case 0xD000: 
  2541.         if (sz == 3) {
  2542.         entry.execfunc = &INST_ADDA;
  2543.         entry.params.mask = x ? 0xffffffff : 0xffff;
  2544.         am1.mode = Areg; am1.reg = r1;
  2545.         } else {
  2546.         entry.execfunc = &INST_ADD;
  2547.         entry.params.mask = sizemask(sz);
  2548.         if (x) {
  2549.             switch(am2.mode) {
  2550.              case Dreg:
  2551.             entry.execfunc = &INST_ADDX;
  2552.             am1.mode = Dreg;
  2553.             am1.reg = r1;
  2554.             break;
  2555.              case Areg:
  2556.             entry.execfunc = &INST_ADDX;
  2557.             am1.mode = am2.mode = Apdi;
  2558.             am1.reg = r1;
  2559.             break;
  2560.              default:
  2561.             am1 = am2;
  2562.             am2.mode = Dreg;
  2563.             am2.reg = r1;
  2564.             break;
  2565.             }
  2566.         } else {
  2567.             am1.mode = Dreg;
  2568.             am1.reg = r1;
  2569.         }
  2570.         }
  2571.         break;      
  2572.      case 0xE000:
  2573.         {
  2574.         int type;
  2575.         
  2576.         if (sz == 3) {
  2577.         entry.params.mask = 0xffff;
  2578.         type = r1*2 + x;
  2579.         switch(type) {
  2580.          case 0: entry.execfunc = &INST_ASR1; break;
  2581.          case 1: entry.execfunc = &INST_ASL1; break;
  2582.          case 2: entry.execfunc = &INST_LSR1; break;
  2583.          case 3: entry.execfunc = &INST_LSL1; break;
  2584.          case 4: entry.execfunc = &INST_ROXR1; break;
  2585.          case 5: entry.execfunc = &INST_ROXL1; break;
  2586.          case 6: entry.execfunc = &INST_ROR1; break;
  2587.          case 7: entry.execfunc = &INST_ROL1; break;
  2588.          default:
  2589.             entry.execfunc = &INST_NIMP; /* 020 bit fiends */
  2590.             break;
  2591.         }
  2592.         if (type < 8) {
  2593.             if (am2.mode == Dreg || am2.mode == Areg || am2.mode == PC16 ||
  2594.             am2.mode == PC8r || am2.mode == imm) {
  2595.             entry.execfunc = &INST_ILLG;
  2596.             }
  2597.         }
  2598.         am1 = am2;
  2599.         } else {
  2600.         type = x + (m2 & 3)*2;
  2601.         entry.params.mask = sizemask(sz);
  2602.         switch(type) {
  2603.          case 0: entry.execfunc = &INST_ASR; break;
  2604.          case 1: entry.execfunc = &INST_ASL; break;
  2605.          case 2: entry.execfunc = &INST_LSR; break;
  2606.          case 3: entry.execfunc = &INST_LSL; break;
  2607.          case 4: entry.execfunc = &INST_ROXR; break;
  2608.          case 5: entry.execfunc = &INST_ROXL; break;
  2609.          case 6: entry.execfunc = &INST_ROR; break;
  2610.          case 7: entry.execfunc = &INST_ROL; break;
  2611.         }
  2612.         am1.mode = Dreg; am1.reg = r2;
  2613.         if (m2 > 3) {
  2614.             am2.mode = Dreg; am2.reg = r1;
  2615.         } else {
  2616.             am2.mode = imm3;
  2617.             am2.reg = r1 ? r1 : 8;
  2618.         }
  2619.         }
  2620.         }
  2621.         break;
  2622.      case 0xF000: 
  2623.         entry.execfunc = &INST_LINEF;
  2624.         break; 
  2625.     }
  2626.     entry.params.dest = am1; entry.params.src = am2;
  2627.     instr_dectab[opcode] = entry;
  2628.     }
  2629. }
  2630.